#include <app\states\modelInfoState.h>
#include <app\states\statesFactory.h>

int modelInfoState::class_type_id = MODEL_INFO_STATE_TYPE_ID;

REGISTER_STATE(MODEL_INFO_STATE_TYPE_ID, modelInfoState);

sessionState *
modelInfoState::create() {
  return new modelInfoState();
} 

void 
modelInfoState::loadInfo(Poco::File file) {
  string fullname = file.path();
  std::fstream input(fullname.c_str(), std::ios::in | std::ios::binary);

  if (input.is_open()) {
    while(!input.eof()) {
      
      string module_name;
      input >> module_name;
      if (module_name == "fileTextureModule") {
        input >> modelInfo.tex_tile_size[0];
        input >> modelInfo.tex_tile_size[1];
        input >> modelInfo.tex_levels_interval[0];
        input >> modelInfo.tex_levels_interval[1];
        input >> modelInfo.tex_level0_offset;
      }
      else if (module_name == "fileTrajectoryModule") {
        input >> modelInfo.traj_tile_size[0];
        input >> modelInfo.traj_tile_size[1];
        input >> modelInfo.traj_levels_interval[0];
        input >> modelInfo.traj_levels_interval[1];
        input >> modelInfo.traj_level0_offset;
      }
      else if (module_name == "fileTerrainModule") {
        input >> modelInfo.terr_tile_size[0];
        input >> modelInfo.terr_tile_size[1];
        input >> modelInfo.terr_levels_interval[0];
        input >> modelInfo.terr_levels_interval[1];
        input >> modelInfo.terr_level0_offset;
      }
      else if (module_name != "") {
        #ifdef DEBUG_INFO
        std::cerr << "ERROR: wrong format of model definition file" << endl;
        #endif
      }
    }
  }
  
  input.close();
}

void 
modelInfoState::saveInfo(Poco::File file) {
  string fullname = file.path();
  std::fstream output(fullname.c_str(), std::ios::out | std::ios::binary);
  if (output.is_open()) {

    output << "fileTextureModule" << endl;
    output << modelInfo.tex_tile_size[0] << endl;
    output << modelInfo.tex_tile_size[1] << endl;
    output << modelInfo.tex_levels_interval[0] << endl;
    output << modelInfo.tex_levels_interval[1] << endl;
    output << modelInfo.tex_level0_offset << endl;

    output << "fileTrajectoryModule" << endl;
    output << modelInfo.traj_tile_size[0] << endl;
    output << modelInfo.traj_tile_size[1] << endl;
    output << modelInfo.traj_levels_interval[0] << endl;
    output << modelInfo.traj_levels_interval[1] << endl;
    output << modelInfo.traj_level0_offset << endl;

    output << "fileTerrainModule" << endl;
    output << modelInfo.terr_tile_size[0] << endl;
    output << modelInfo.terr_tile_size[1] << endl;
    output << modelInfo.terr_levels_interval[0] << endl;
    output << modelInfo.terr_levels_interval[1] << endl;
    output << modelInfo.terr_level0_offset << endl;
  }
  output.close();
}

void
modelInfoState::loadFromRawData(unsigned char *data, int size) {
  stringstream ss;//(ios::in | ios::out | ios::binary);
  ss.write((const char *) data, size);
  ss.seekg(0, ios::beg);

  while(!ss.eof()) {
    string module_name;
    ss >> module_name;
    if (module_name == "fileTextureModule") {
      ss >> modelInfo.tex_tile_size[0];
      ss >> modelInfo.tex_tile_size[1];
      ss >> modelInfo.tex_levels_interval[0];
      ss >> modelInfo.tex_levels_interval[1];
      ss >> modelInfo.tex_level0_offset;
    }
    else if (module_name == "fileTrajectoryModule") {
      ss >> modelInfo.traj_tile_size[0];
      ss >> modelInfo.traj_tile_size[1];
      ss >> modelInfo.traj_levels_interval[0];
      ss >> modelInfo.traj_levels_interval[1];
      ss >> modelInfo.traj_level0_offset;
    }
    else if (module_name == "fileTerrainModule") {
      ss >> modelInfo.terr_tile_size[0];
      ss >> modelInfo.terr_tile_size[1];
      ss >> modelInfo.terr_levels_interval[0];
      ss >> modelInfo.terr_levels_interval[1];
      ss >> modelInfo.terr_level0_offset;
    }
    else if (module_name != "") {
      #ifdef DEBUG_INFO
      cerr << "ERROR: wrong format of model definition file" << endl;
      #endif
    }
  }
}

unsigned char *
modelInfoState::getRawData(int &size) {
  stringstream ss("", ios::in | ios::out | ios::binary);

  ss << "fileTextureModule" << endl;
  ss << modelInfo.tex_tile_size[0] << endl;
  ss << modelInfo.tex_tile_size[1] << endl;
  ss << modelInfo.tex_levels_interval[0] << endl;
  ss << modelInfo.tex_levels_interval[1] << endl;
  ss << modelInfo.tex_level0_offset << endl;

  ss << "fileTrajectoryModule" << endl;
  ss << modelInfo.traj_tile_size[0] << endl;
  ss << modelInfo.traj_tile_size[1] << endl;
  ss << modelInfo.traj_levels_interval[0] << endl;
  ss << modelInfo.traj_levels_interval[1] << endl;
  ss << modelInfo.traj_level0_offset << endl;

  ss << "fileTerrainModule" << endl;
  ss << modelInfo.terr_tile_size[0] << endl;
  ss << modelInfo.terr_tile_size[1] << endl;
  ss << modelInfo.terr_levels_interval[0] << endl;
  ss << modelInfo.terr_levels_interval[1] << endl;
  ss << modelInfo.terr_level0_offset << endl; 

  ss.seekg(0, ios::end);
  size = ss.tellg();
  ss.seekg(0, ios::beg);

  unsigned char *data = new unsigned char[size];
  ss.read((char *) data, size);

  return data;
}  

void 
modelInfoState::setModelInfoReceived(bool value) {
  received = value;
}

bool 
modelInfoState::modelInfoReceived() {
  return received;
}

sModelInfo
modelInfoState::info() {
  return modelInfo;
}

int 
modelInfoState::getClassTypeId() {
  return modelInfoState::class_type_id;
}

int
modelInfoState::getTypeId() {
  return type_id;
}

modelInfoState::modelInfoState() : type_id(MODEL_INFO_STATE_TYPE_ID) {
  received = false;
}

modelInfoState::~modelInfoState() {

}
